/* Orbas:
 *     A open source CORBA Specification implementation from Huihoo.
 *
 * Copyright 2002-2003 Huihoo.org, Inc. All Right Reserved.
 *
 * This software is licensed under LGPL license.
 * See terms of license at gnu.org.
 *
 * For more information, visit:
 *
 * http://www.huihoo.org/orbas
 */

package org.huihoo.orbas.poa;

/**
 * <p>Description: </p>
 * A processor of RequestEntry.
 * <p>Copyright (c) 2003</p>
 * <p>Company: <a href="http://www.huihoo.org/orbas">huihoo.org</a></p>
 * @author <a href="http://www.huihoo.org/~cocia">Cocia Lin(cocia@163.com)</a>
 * @see <a href="http://www.huihoo.org/orbas">http://www.huihoo.org/orbas</a>
 * @version 1.0
 */

import org.huihoo.orbas.util.Logger;
import org.huihoo.orbas.util.LoggerFactory;
import org.omg.CORBA.portable.OutputStream;
import org.omg.PortableServer.POAManagerPackage.State;

public class RequestProcessor {

	// ~
	private boolean started;
	private boolean terminaled;
	private org.omg.PortableServer.POA poa;
	private RequestEntry requestEntry;
	// Logger tool.
	private static Logger logger = LoggerFactory.getLogger("POA_Processor");

	//
	public RequestProcessor() {
		logger.debug("RequestProcessor constructed.");
	}

	public void init(org.omg.PortableServer.POA poa, RequestEntry reqEntry) {
		this.poa = poa;
		this.requestEntry = reqEntry;
	}

	/**
	 * Clear this processor for reuseable.
	 */
	public void destory() {
		this.poa = null;
		this.requestEntry = null;
	}

	/**
	 * from corba 3.0 02-12-02 page 406 [Active State] When a POA manager is in
	 * the active state, the associated POAs will receive and start processing
	 * requests (assuming that appropriate thread resources are available). Note
	 * that even in the active state, a POA may need to queue requests depending
	 * upon the ORB implementation and resource limits. The number of requests
	 * that can be received and/or queued is an implementation limit. If this
	 * limit is reached, the POA should return a TRANSIENT system exception,
	 * with standard minor code 1, to indicate that the client should re-issue
	 * the request. A user program can legally transition a POA manager from the
	 * active state to either the discarding, holding, or inactive state by
	 * calling the discard_requests, hold_requests, or deactivate operations,
	 * respectively. The POA enters the active state through the use of the
	 * activate operation when in the discarding or holding state.
	 * ////////////////////////// [Holding State] When a POA manager is in the
	 * holding state, the associated POAs will queue incoming requests. The
	 * number of requests that can be queued is an implementation limit. If this
	 * limit is reached, the POAs may discard requests and return the TRANSIENT
	 * system exception, with standard minor code 1, to the client to indicate
	 * that the client should reissue the request. (Of course, an ORB may always
	 * reject a request for other reasons and raise some other system
	 * exception.) In addition, when a POA manager is in the holding state, the
	 * adapter activators registered with the associated POAs will not get
	 * called. Instead, requests that require the invocation of an adapter
	 * activator will be queued, as described in the previous paragraph. A POA
	 * manager can legally transition from the holding state to either the
	 * active, discarding, or inactive state by calling the activate,
	 * discard_requests, or deactivate operations, respectively. The POA enters
	 * the holding state through the use of the hold_requests operation when in
	 * the active or discarding state. A POA manager is created in the holding
	 * state.
	 */
	protected void process() {
		logger.debug("RequestProcessor process.");
		//
		State state = poa.the_POAManager().get_state();
		switch (state.value()) {
		case State._ACTIVE:
			/*
			 * catch _is_a and _get_interface_def and _is_equivalent and
			 * _non_existent method here for invoke it from delegate.
			 */
			if ("_is_a".equals(requestEntry.getMethodName())) {
				String repid = requestEntry.getInputStream().read_string();
				boolean ret = requestEntry.getServant()._is_a(repid);
				OutputStream out = requestEntry.getResponseHandler()
						.createReply();
				out.write_boolean(ret);
				requestEntry.setOutputStream(out);
			} else if ("_get_interface_def"
					.equals(requestEntry.getMethodName())) {
				org.omg.CORBA.Object ret = requestEntry.getServant()
						._get_interface_def();
				OutputStream out = requestEntry.getResponseHandler()
						.createReply();
				out.write_Object(ret);
				requestEntry.setOutputStream(out);

			} else if ("_is_equivalent".equals(requestEntry.getMethodName())) {
				throw new org.omg.CORBA.NO_IMPLEMENT();

			} else if ("_non_existent".equals(requestEntry.getMethodName())) {
				boolean ret = requestEntry.getServant()._non_existent();
				OutputStream out = requestEntry.getResponseHandler()
						.createReply();
				out.write_boolean(ret);
				requestEntry.setOutputStream(out);

			} else {
				// Invoke user custom method here.
				requestEntry.setOutputStream(requestEntry.getInvokeHandler()
						._invoke(requestEntry.getMethodName(),
								requestEntry.getInputStream(),
								requestEntry.getResponseHandler()));

			}

			//
			break;
		case State._HOLDING:
			logger.debug("Enter HOLDING handler...");
			// To esay handle this state,we discard all the request here.
			org.omg.CORBA.portable.OutputStream _output = requestEntry
					.getResponseHandler().createExceptionReply();
			requestEntry.setOutputStream(_output);
			//
			org.omg.CORBA.TRANSIENT e = new org.omg.CORBA.TRANSIENT(1,
					org.omg.CORBA.CompletionStatus.COMPLETED_NO);
			_output.write_Object((org.omg.CORBA.Object) e);

			break;
		case State._DISCARDING:
		case State._INACTIVE:
			logger.debug("Orbas not support this state now.");
			break;
		default:
			// error state.
			logger.debug("Not found any method to invoke.");

		}

	}

}